package com.lagou.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lagou.dao.OrderDao;
import com.lagou.enumration.OrderResponseCodeEnum;
import com.lagou.enumration.OrderStatusEnum;
import com.lagou.model.Response;
import com.lagou.model.dto.AddOrderResp;
import com.lagou.model.dto.PayOrderReq;
import com.lagou.model.dto.PayOrderResp;
import com.lagou.model.entity.OrderDO;
import com.lagou.service.OrderService;
import java.io.UnsupportedEncodingException;
import java.util.UUID;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;


@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<AddOrderResp> addOrder(Integer customerId)
        throws JsonProcessingException, UnsupportedEncodingException {
        // 保存订单
        OrderDO orderDo = new OrderDO();
        orderDo.setCustomerId(1);
        orderDo.setStatus(OrderStatusEnum.NOT_PAY.getValue());
        orderDao.save(orderDo);

        // 发送订单信息到订单取消队列
        MessageProperties props = new MessageProperties();
        props.setContentType(MessageProperties.CONTENT_TYPE_JSON);
        props.setContentEncoding("utf-8");
        props.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
        CorrelationData cd = new CorrelationData();
        cd.setId(UUID.randomUUID().toString());
        cd.setReturnedMessage(new Message(objectMapper.writeValueAsString(orderDo).getBytes("utf-8"), props));
        rabbitTemplate.convertAndSend("ex.order", "order.cancel", orderDo, cd);
        // TODO 持久化未确认消息，用于补偿
        return new Response<>(new AddOrderResp(orderDo.getId()));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Response<PayOrderResp> payOrder(Integer orderId) {
        Optional<OrderDO> orderDOOptional = orderDao.findById(orderId);
        if (!orderDOOptional.isPresent()) {
            return new Response<>(OrderResponseCodeEnum.ORDER_NOT_EXIST.getCode(), OrderResponseCodeEnum.ORDER_NOT_EXIST.getDesc());
        }

        OrderDO orderDO = orderDOOptional.get();
        if (!orderDO.getStatus().equals(OrderStatusEnum.NOT_PAY.getValue())) {
            return new Response<>(new PayOrderResp(orderDO.getStatus(), orderDO.getPayOrderId()));
        }

        int count = orderDao.updateOrderStatusByStatus(orderDO.getId(),
                OrderStatusEnum.NOT_PAY.getValue(), OrderStatusEnum.HAS_PAID.getValue());
        if (count <= 0) {
            orderDOOptional = orderDao.findById(orderId);
            orderDO = orderDOOptional.get();
            return new Response<>(new PayOrderResp(orderDO.getStatus(), orderDO.getPayOrderId()));
        }

        // TODO 转账支付逻辑，获取payOrderId回填到订单
        orderDO = orderDao.findById(orderId).get();
        orderDO.setPayOrderId("1");
        orderDao.save(orderDO);
        return new Response<>(new PayOrderResp(OrderStatusEnum.HAS_PAID.getValue(), orderDO.getPayOrderId()));
    }
}
